package com.spzx.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.web.controller.BaseController;
import com.spzx.common.core.web.domain.AjaxResult;
import com.spzx.common.rabbit.constant.MqConst;
import com.spzx.common.rabbit.service.RabbitService;
import com.spzx.common.security.annotation.RequiresLogin;
import com.spzx.order.api.domain.OrderInfo;
import com.spzx.order.api.service.RemoteOrderInfoService;
import com.spzx.payment.config.AlipayConfig;
import com.spzx.payment.domain.PaymentInfo;
import com.spzx.payment.service.AlipayService;
import com.spzx.payment.service.PaymentInfoService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping("/alipay")
public class AlipayController extends BaseController {

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PaymentInfoService paymentInfoService;

    @Autowired
    private RemoteOrderInfoService remoteOrderInfoService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private PaymentInfo paymentInfo;

    @Operation(summary = "支付宝下单")
    @RequiresLogin
    @RequestMapping("/submitAlipay/{orderNo}")
    @ResponseBody
    public AjaxResult submitAlipay(@PathVariable(value = "orderNo") String orderNo) {
        String form = alipayService.submitAlipay(orderNo);
        return success(form);
    }

    @RequestMapping("/callback/notify")
    @ResponseBody
    public String alipayNotify(@RequestParam Map<String, String> paramMap, HttpServletRequest request) {
        log.info("AlipayController...alipayNotify方法执行了...");
        return "success";
    }

    @PostMapping("/callback/notify")
    @ResponseBody
    public String alipayNotify(@RequestParam Map<String, String> paramMap) {

        log.info("alipayNotify方法执行了...");

        String result = "failure";

        try {
            //调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    paramMap,
                    AlipayConfig.alipay_public_key,
                    AlipayConfig.charset,
                    AlipayConfig.sign_type
            );


            //校验验签是否成功
            String outTradeNo = paramMap.get("out_trade_no");
            if (!signVerified) {
                log.error("订单 {} 验签失败", outTradeNo);
                return result;
            }
            log.error("验签成功！");

            //商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。
            R<OrderInfo> orderInfoResult = remoteOrderInfoService.getByOrderNo(outTradeNo, SecurityConstants.INNER);
            if (R.FAIL == orderInfoResult.getCode()) {
                log.error("远程获取订单 {} 失败", outTradeNo);
                return result;
            }
            if (orderInfoResult.getData() == null) {
                log.error("订单 {} 不存在", outTradeNo);
                return result;
            }
            OrderInfo orderInfo = orderInfoResult.getData();

            // 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）。
            String totalAmount = paramMap.get("total_amount");
            if (orderInfo.getTotalAmount().compareTo(new BigDecimal(totalAmount)) != 0) {
                log.error("订单 {} 金额不一致", outTradeNo);
                return result;
            }

            // 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方（有的时候，一个商家可能有多个 seller_id/seller_email）。
            // "2088721032347805" 沙箱中的 商户PID
            String sellerId = paramMap.get("seller_id");
            if (!"2088721032347805".equals(sellerId)) {
                log.error("订单 {} 商家不一致", outTradeNo);
                return result;
            }

            //验证 app_id 是否为该商家本身。
            String appId = paramMap.get("app_id");
            if (!AlipayConfig.app_id.equals(appId)) {
                log.error("订单 {} appid不一致", outTradeNo);
                return result;
            }

            // 交易状态
            String tradeStatus = paramMap.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 正常的支付成功，我们应该更新交易记录状态
                paymentInfoService.updatePaymentStatus(paramMap, 2);

                //基于MQ通知订单系统，修改订单状态
                rabbitService.sendMessage(MqConst.EXCHANGE_PAYMENT_PAY, MqConst.ROUTING_PAYMENT_PAY, paymentInfo.getOrderNo());
                //基于MQ通知商品系统，扣减库存
                rabbitService.sendMessage(MqConst.EXCHANGE_PRODUCT, MqConst.ROUTING_MINUS, outTradeNo);

                return "success";
            }

        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        return result;
    }

}
